package com.tanhua.server.service;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.tanhua.autoconfig.template.HuanXinTemplate;
import com.tanhua.commons.Constants;
import com.tanhua.dubbo.api.db.SettingApi;
import com.tanhua.dubbo.api.db.UserApi;
import com.tanhua.dubbo.api.db.UserInfoApi;
import com.tanhua.dubbo.api.mongo.RecommendUserApi;
import com.tanhua.dubbo.api.mongo.SearchApi;
import com.tanhua.dubbo.api.mongo.UserLikeApi;
import com.tanhua.dubbo.api.mongo.VisitorsApi;
import com.tanhua.model.db.UserInfo;
import com.tanhua.model.mongo.RecommendUser;
import com.tanhua.model.mongo.Visitors;
import com.tanhua.model.vo.*;
import com.tanhua.server.interceptor.UserHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
public class TanhuaService {

    @Autowired
    private HuanXinTemplate huanXinTemplate;

    @DubboReference
    private RecommendUserApi recommendUserApi;

    @DubboReference
    private UserInfoApi userInfoApi;

    @DubboReference
    private SettingApi settingApi;

    @DubboReference
    private UserLikeApi userLikeApi;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @DubboReference
    private UserApi userApi;

    @DubboReference
    private SearchApi searchApi;

    @DubboReference
    private VisitorsApi visitorsApi;


    /**
     * 获取今日佳人
     *
     * @return
     */
    public TodayBest todayBest() {
        RecommendUser recommendUser = recommendUserApi.getTodayBest(UserHolder.getUserId());
        if (recommendUser == null) {
            recommendUser = new RecommendUser();
            recommendUser.setUserId(UserHolder.getUserId() % 99 + 1);
            recommendUser.setScore(90d);
            recommendUser.setToUserId(UserHolder.getUserId());

        }
        UserInfo getuserinfo = userInfoApi.getuserinfo(recommendUser.getUserId(), null);
        TodayBest todayBest = TodayBest.init(getuserinfo, recommendUser);

        return todayBest;
    }

    /**
     * 佳人信息
     *
     * @param id
     * @return
     */
    public TodayBest personalInfo(Long id) {
        RecommendUser recommendUser = recommendUserApi.getBast(id, UserHolder.getUserId());
        UserInfo getuserinfo = userInfoApi.getuserinfo(id, null);
        Double score = Double.valueOf(63+id+UserHolder.getUserId()%10);
        if(null != recommendUser){
            score = recommendUser.getScore();
        }
        TodayBest todayBest = TodayBest.init(getuserinfo, recommendUser);
        if (UserHolder.getUserId().longValue() != id.longValue()){
            // 保存访客记录, 最好由MQ来实现  Topic模式：visitors.log  #.log  visitors.*
            Visitors visitors = new Visitors();
            visitors.setFrom("首页");
            visitors.setVisitorUserId(UserHolder.getUserId());
            visitors.setUserId(id);
            visitors.setScore(score);
            visitorsApi.save(visitors);
        }
        return todayBest;
    }

    /**
     * 获取推荐列表
     */
    public PageResult<TodayBest> recommenDation(RecommendUserQueryParam recommendUserQueryParam) {
        PageResult<RecommendUser> result = recommendUserApi.getrecommenDation(UserHolder.getUser(), recommendUserQueryParam);
        List<RecommendUser> recommendUserList = result.getItems();
        List<TodayBest> voList = new ArrayList<>();
        //1.1 如果没有推荐的佳人，则给客服，默认只给1页的数据
        if (CollectionUtil.isEmpty(recommendUserList) && recommendUserQueryParam.getPage() == 1) {
            recommendUserList = getDefaultRecommendUser();
        }
        //判断是否有数据
        if (CollectionUtil.isNotEmpty(recommendUserList)) {
            //2. 获取所有佳人的id放到list集合
            //List<Long> userIds = recommendUserList.stream().map(RecommendUser::getUserId).collect(Collectors.toList());
            List<Long> userIds = new ArrayList<>();
            for (RecommendUser recommendUser : recommendUserList) {
                userIds.add(recommendUser.getUserId());
            }
            //3. 批量查询佳人信息(条件过滤)
            // key=用户id, value=用户信息, 佳人信息. 【注意】数量可能少于userIds。有些佳人因不满足条件而被过滤了.userInfoMap.size<=userIds(recommendUserList)
            Map<Long, UserInfo> userInfoMap = userInfoApi.getUserList(userIds, getUserCondition(recommendUserQueryParam));
            //4. 转成vo,
            for (RecommendUser recommendUser : recommendUserList) {
                // 佳人id
                Long userId = recommendUser.getUserId();
                // 佳人信息, 【注意】userInfo有可能是空值，因为条件不满足被排除掉了
                UserInfo userInfo = userInfoMap.get(userId);
                if (null != userInfo) {
                    TodayBest vo = TodayBest.init(userInfo, recommendUser);
                    voList.add(vo);
                }
            }
        }
        // 设置到pageResult

        //5. 返回pageResult
        return new PageResult(result.getPage(), result.getPagesize(), result.getCounts(), voList);
    }

    /**
     * 构建查询用户详情时的过滤条件
     *
     * @param queryParam
     * @return
     */
    private UserInfo getUserCondition(RecommendUserQueryParam queryParam) {
        UserInfo userInfoCondition = new UserInfo();
        userInfoCondition.setAge(queryParam.getAge()); // 使用小于
        userInfoCondition.setGender(queryParam.getGender());
        return userInfoCondition;
    }

    /**
     * 默认客服
     *
     * @return
     */
    private List<RecommendUser> getDefaultRecommendUser() {
        List<RecommendUser> list = new ArrayList<>();
        for (long i = 1; i <= 10; i++) {
            RecommendUser recommendUser = new RecommendUser();
            recommendUser.setUserId(i);
            recommendUser.setScore(Double.valueOf(63 + i + UserHolder.getUserId() % 10));
            //【注意】要添加到list
            list.add(recommendUser);
        }
        return list;
    }

    /**
     * 查询陌生人问题
     *
     * @param userId
     * @return
     */
    public String strangerQuestions(Long userId) {
        String questions = settingApi.getQuestions(userId);
        return questions;
    }

    /**
     * 探花
     *
     * @return
     */
    public List<CardsVo> getCards() {
        String likeKey = Constants.USER_LIKE_KEY + UserHolder.getUserId();
        String notLikeKey = Constants.USER_NOT_LIKE_KEY + UserHolder.getUserId();
        PageResult<RecommendUser> result = recommendUserApi.getrecommenDation(UserHolder.getUser(), new RecommendUserQueryParam());
        List<RecommendUser> items = result.getItems();
        List<Long> longList = items.stream().map(RecommendUser::getUserId).collect(Collectors.toList());
        List<UserInfo> usersByid = userInfoApi.getUsersByid(longList);
        List<CardsVo> voList = new ArrayList<>();
        for (UserInfo userInfo : usersByid) {
            if (!stringRedisTemplate.opsForSet().isMember(likeKey, userInfo.getId().toString()) && !stringRedisTemplate.opsForSet().isMember(notLikeKey, userInfo.getId().toString())) {
                CardsVo cardsVo = CardsVo.init(userInfo);
                voList.add(cardsVo);
            }

        }
        return voList;
    }

    /**
     * 右滑喜欢 -- 左滑不喜欢

     * @param id
     */
    public void loveUser(Long id, Boolean isLike) {
        if (isLike) {
            Boolean like = userLikeApi.loveUser(id, UserHolder.getUserId());
            String likeKey = Constants.USER_LIKE_KEY + UserHolder.getUserId();
            String notLikeKey = Constants.USER_NOT_LIKE_KEY + UserHolder.getUserId();
            stringRedisTemplate.opsForSet().add(likeKey, id.toString());
            if (stringRedisTemplate.opsForSet().isMember(notLikeKey, id.toString())) {
                stringRedisTemplate.opsForSet().remove(notLikeKey, id.toString());
            }
            if (like) {

                huanXinTemplate.addContact(UserHolder.getUser().getHxUser(), Constants.HX_USER_PREFIX + id);
            }

        }

        if (!isLike) {
            userLikeApi.notLikeUser(id, UserHolder.getUserId());
            String notLikeKey = Constants.USER_NOT_LIKE_KEY + UserHolder.getUserId();
            String likeKey = Constants.USER_LIKE_KEY + UserHolder.getUserId();
            if (stringRedisTemplate.opsForSet().isMember(likeKey, id.toString())) {
                stringRedisTemplate.opsForSet().remove(likeKey, id.toString());
            }
            stringRedisTemplate.opsForSet().add(notLikeKey, id.toString());
        }
    }

    /**
     * 回复陌生人问题
     *
     * @param params
     */
    public void sendStrangerQuestions(Map<String, Object> params) {
        Integer userId = (Integer) params.get("userId");
        log.info("前端传的ID是：====" + userId.toString());
        UserInfo userInfo = userInfoApi.getuserinfo(UserHolder.getUserId(), null);
        String questions = settingApi.getQuestions(userId.longValue());
        Map<String, Object> replys = new HashMap<>();
        replys.put("userId", UserHolder.getUserId());
        replys.put("huanxinId", UserHolder.getUser().getHxUser());
        replys.put("nickname", userInfo.getNickname());
        replys.put("strangerQuestion", null == questions ? "有人给你打招呼了" : questions);
        replys.put("reply", params.get("reply"));

        huanXinTemplate.sendMsg(Constants.HX_USER_PREFIX + userId, JSON.toJSONString(replys));

    }

    /**
     * 搜索附近的人
     *
     * @param gender
     * @param distance
     * @return
     */
    public List<NearUserVo> findSearch(String gender, Long distance) {

        List<Long> userIds = searchApi.findSearch(UserHolder.getUserId(), distance);

        List<NearUserVo> userVoList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(userIds)) {
            UserInfo userInfo = new UserInfo();
            userInfo.setGender(gender);
            Map<Long, UserInfo> userList = userInfoApi.getUserList(userIds, userInfo);
            userVoList = userList.values().stream().map(u -> NearUserVo.init(u)).collect(Collectors.toList());

        }
        return userVoList;
    }
}
